﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Sahit.iSoilHotel.Infrastructure.Web.Framework;
using Sahit.iSoilHotel.Infrastructure.Web.Configuration;
using Sahit.iSoilHotel.Infrastructure.Core.Helper;

namespace Sahit.iSoilHotel.Infrastructure.Web.DependencyManagement
{
    public class ContainerConfigurer
    {
        public static class ConfigurationKeys
        {
            public const string MediumTrust = "MediumTrust";
            public const string FullTrust = "FullTrust";
        }

        public virtual void Configure(IEngine engine, ContainerManager containerManager, EventBroker broker, SoilConfig configuration)
        {
            containerManager.AddComponentInstance<SoilConfig>(configuration, "soil.configuration");
            containerManager.AddComponentInstance<IEngine>(engine, "soil.engine");
            containerManager.AddComponentInstance<ContainerConfigurer>(this, "soil.containerConfigurer");

            containerManager.AddComponent<ITypeFinder, WebAppTypeFinder>("soil.typeFinder");

            var typeFinder = containerManager.Resolve<ITypeFinder>();
            containerManager.UpdateContainer(x =>
            {
                var drTypes = typeFinder.FindClassesOfType<IDependencyRegistrar>();
                var drInstances = new List<IDependencyRegistrar>();
                foreach (var drType in drTypes)
                    drInstances.Add((IDependencyRegistrar)Activator.CreateInstance(drType));

                drInstances = drInstances.AsQueryable().OrderBy(t => t.Order).ToList();
                foreach (var dependencyRegistrar in drInstances)
                    dependencyRegistrar.Register(x, typeFinder);
            });

            containerManager.AddComponentInstance(broker);

            containerManager.AddComponent<DependencyAttributeRegistrator>("soil.serviceRegistrator");
            var registrator = containerManager.Resolve<DependencyAttributeRegistrator>();
            var services = registrator.FindServices();
            var configurations = GetComponentConfigurations(configuration);
            services = registrator.FilterServices(services, configurations);
            registrator.RegisterServices(services);
        }

        protected virtual string[] GetComponentConfigurations(SoilConfig configuration)
        {
            var configurations = new List<string>();
            string trustConfiguration = (CommonHelper.GetTrustLevel() > System.Web.AspNetHostingPermissionLevel.Medium)
                ? ConfigurationKeys.FullTrust
                : ConfigurationKeys.MediumTrust;
            configurations.Add(trustConfiguration);
            return configurations.ToArray();
        }
    }
}
